package com.dliu.javadesign.create.singleton;

import java.util.concurrent.atomic.AtomicReference;

/**
 * @author yanglei
 * date 2021/3/30 10:43
 */
public class Singleton {

    /**
     * 1，枚举方式（推荐）
     */
    enum EnumSingleton {
        ENUM_SINGLETON,
        ;
        private final Singleton singleton;

        EnumSingleton() {
            singleton = new Singleton();
        }

        public Singleton getSingleton(){
            return singleton;
        }

        public static void main(String[] args) {
            Singleton singleton = EnumSingleton.ENUM_SINGLETON.getSingleton();
            Singleton singleton1 = EnumSingleton.ENUM_SINGLETON.getSingleton();
            System.out.println(singleton);
            System.out.println(singleton1);
        }
    }

}

/**
 * 2，静态成员变量
 */
class StaticSingleton {
    public static Singleton singleton = new Singleton();

    public static void main(String[] args) {
        System.out.println(StaticSingleton.singleton);
        System.out.println(StaticSingleton.singleton);
    }
}

/**
 * 3, 懒汉式（线程不安全）
 */
class LazySingleton {
    private static LazySingleton instance;

    private LazySingleton(){

    }

    public static LazySingleton getInstance(){
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

/**
 * 4，饿汉式（线程安全）
 */
class HungerSingleton {
    private static final HungerSingleton instance = new HungerSingleton();

    private HungerSingleton(){

    }

    public static HungerSingleton getInstance(){
        return instance;
    }
}

/**
 * 5，静态内部类（线程安全+懒加载）
 */
class InnerSingleton {
    private static class Inner {
        public static InnerSingleton instance = new InnerSingleton();
    }
    private InnerSingleton() {

    }

    public static InnerSingleton getInstance(){
        return Inner.instance;
    }
}

/**
 * 6，双重校验单例（线程安全）
 */
class DCLSingleton {
    private static DCLSingleton instance;

    private DCLSingleton(){}

    public static DCLSingleton getInstance(){
        if (instance == null) {
            synchronized (DCLSingleton.class){
                if (instance == null) {
                    instance = new DCLSingleton();
                }
            }
        }
        return instance;
    }
}

/**
 * 7，CAS（线程安全）
 */
class CASSingleton {
    private static AtomicReference<CASSingleton> instance = new AtomicReference<>();

    private CASSingleton(){}

    public static CASSingleton getInstance(){
        while (true){
            CASSingleton casSingleton = instance.get();
            if (casSingleton != null){
                return casSingleton;
            }
            instance.compareAndSet(null, new CASSingleton());
            return instance.get();
        }
    }

    public static void main(String[] args) {
        System.out.println(CASSingleton.getInstance());
        System.out.println(CASSingleton.getInstance());
    }
}
